<?php

namespace App\Request\auth\Service\Auth;

use App\Exception\BusinessException;
use App\Model\Auth\Admin;
use App\Repository\Auth\AdminRepository;
use App\Repository\Auth\AdminRoleRepository;
use App\Request\auth\Service\IService;
use App\Request\auth\Service\Jwt\JwtService;
use Exception;
use Hyperf\Context\ApplicationContext;
use Hyperf\DbConnection\Db;
use function App\Helper\listToTree;


/**
 * 管理员服务
 */
class AdminService extends IService
{


    public function __construct(
        protected readonly AdminRepository  $repository,
        protected readonly AdminRoleService $adminRoleService,
        protected readonly MenuService      $menuService,
        protected readonly JwtService       $jwtService,
    )
    {
    }


    public function page(array $params, int $page = 1, int $pageSize = 10): array
    {
        $data = parent::page($params, $page, $pageSize);
        foreach ($data['list'] as &$item) {
            $item['role_id'] = $this->adminRoleService->getRoleIdByAdminId($item['id']);
            $item['role_name'] = $this->adminRoleService->getRoleNameByRoleId($item['id']);
        }
        return $data;

    }

    /**
     * 创建\编辑管理员
     * @param mixed $id
     * @param array $data
     * @return mixed
     * @throws Exception
     */
    public function updateById(mixed $id, array $data): mixed
    {
        return Db::transaction(function () use ($id, $data) {
            // 校验账号重复
            $query = $this->repository->getQuery()->where('account', $data['account']);
            if (!empty($id)) {
                $query->where('id', '<>', $id);
            }

            if ($query->exists()) {
                throw new BusinessException('该账号已存在，请更换账号');
            }

            // 新增或更新管理员
            if (empty($id)) {
                if (empty($data['password'])) {
                    throw new BusinessException('新增管理员时必须设置密码');
                }
                $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
                $model = $this->create($data);
                $id = $model->id;
            } else {
                // 如果密码存在且不为空，才加密
                if (!empty($data['password'])) {
                    $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
                } else {
                    unset($data['password']); // 避免更新时将密码设置为 null
                }
                parent::updateById($id, $data);
            }

            // 同步角色权限（新增或编辑都执行）
            $this->adminRoleService->batchInsert($id, $data['role_id'] ?? []);

            return $id;
        });
    }


    /**
     * 删除管理员
     * @param mixed $id
     * @return int
     * @throws Exception
     */
    public function deleteById(mixed $id): int
    {
        // 不可删除的管理员
        $notDelete = [1];
        if (in_array($id, $notDelete)) {
            throw new BusinessException('不可删除管理员');
        }
        //删除角色管理员关联表
        $adminRoleRepository = ApplicationContext::getContainer()->get(AdminRoleRepository::class);
        $adminRoleRepository->getQuery()->where('admin_id', $id)->delete();
        return parent::deleteById($id);
    }

    /**
     * 获取当前权限菜单
     * @param int $adminId
     * @return array[]
     * @throws Exception
     */
    public function mySelf(int $adminId): array
    {
        $res = [
            // 菜单列表
            /** @lang text */
            'menu' => [],
            // 权限列表 按钮类
            'permissions' => [],
        ];
        $adminInfo = $this->repository->getQuery()->find($adminId);
        //判断管理员账号是否被禁用
        if ($adminInfo->status != 1) {
            //清除登录
            throw new BusinessException('账号被禁用');
        }
        $roles = [];
        foreach ($adminInfo->role->where('status', 1) as $role) {
            //获取角色的菜单id
            $roles[] = $role->rules;
        }
        //判断是否是超级管理员
        if (in_array('*', $roles)) {
            //获取所有菜单
            $res['menu'] = listToTree($this->menuService->getMenus("*")->toArray());
            $res['permissions'] = $this->menuService->getPermission("*");
        } else {
            //普通用户
            $roles = call_user_func_array('array_merge', $roles);
            $res['menu'] = listToTree($this->menuService->getMenus($roles)->toArray());
            $res['permissions'] = $this->menuService->getPermission($roles);

        }

        return $res;
    }

    /**
     * 编辑当前管理员
     * @param int $adminId
     * @param array $params
     * @return void
     * @throws Exception
     */
    public function editCurrentAdmin(int $adminId, array $params): void
    {
        if ($params['newPassword'] && $params['newPassword'] != $params['confirmPassword']) {
            throw new BusinessException('密码不一致');
        }
        if ($params['newPassword']) {
            $params['password'] = password_hash($params['newPassword'], PASSWORD_DEFAULT);
        }
        unset($params['newPassword'], $params['confirmPassword']);
        $this->updateById($adminId, $params);
    }

    /**
     * 后台授权
     * @throws Exception
     */
    public function login(string $username, string $password): array
    {
        $admin = Admin::query()->where(['account' => $username])->first();
        if (!$admin) {
            throw  new BusinessException('用户不存在');
        }
        if (!password_verify($password, $admin->password)) {
            throw  new BusinessException('密码错误');
        }
        if ($admin->status != 1) {
            throw  new BusinessException('用户被禁用');
        }
        $token = $this->jwtService->getToken($admin->id);
        return array_merge($admin->toArray(), ['token' => $token]);
    }

}